// SSH连接模块 - 实现SSH连接、认证和会话管理功能
// 参考RustDesk的网络连接实现方式，提供异步SSH连接处理

use std::{
    collections::HashMap,  // 用于存储多个SSH连接的映射表
    sync::Arc,            // 原子引用计数，用于多线程安全的共享数据
    time::{Duration, Instant}, // 时间相关类型，用于超时和时间戳
    io::Read,             // 用于读取数据流
    path::Path,           // 文件路径处理
};

use tokio::{
    sync::{Mutex, RwLock}, // 异步互斥锁和读写锁，用于并发控制
    time::timeout,         // 异步超时功能
};

use ssh2::{
    Channel,     // SSH通道，用于执行命令和数据传输
    Session,     // SSH会话，表示一个SSH连接
    Stream,      // SSH数据流
};

use std::{
    net::TcpStream,    // TCP网络流
};

use crate::{
    config::ConnectionConfig, // 连接配置结构体
    terminal::TerminalEvent,  // 终端事件类型
};

// SSH连接状态枚举 - 表示连接的不同状态
#[derive(Debug, Clone, PartialEq)]
pub enum ConnectionStatus {
    Disconnected,  // 未连接状态
    Connecting,    // 正在连接状态
    Connected,     // 已连接状态
    Error(String), // 错误状态，包含错误信息
}

// SSH认证方法枚举 - 支持的认证方式
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub enum AuthMethod {
    Password(String),           // 密码认证，包含密码字符串
    PublicKey {
        private_key_path: String,  // 私钥文件路径
        passphrase: Option<String>, // 私钥密码（可选）
    },
    Agent,                      // SSH Agent认证
}

// SSH配置结构体 - 包含SSH连接的所有配置信息
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SshConfig {
    pub host: String,                    // 主机地址
    pub port: u16,                       // 端口号
    pub username: String,                // 用户名
    pub auth_method: AuthMethod,         // 认证方法
    pub password: Option<String>,        // 密码（可选）
    pub private_key_path: Option<String>, // 私钥路径（可选）
    pub connect_timeout: Option<u64>,    // 连接超时时间（秒）
    pub keepalive_interval: Option<u64>, // 保活间隔（秒）
}

// SSH连接结构体 - 管理SSH连接的生命周期和状态
pub struct SshConnection {
    pub id: String,                           // 连接唯一标识符
    pub config: ConnectionConfig,             // 连接配置信息
    pub status: Arc<RwLock<ConnectionStatus>>, // 连接状态（线程安全）
    pub session: Arc<Mutex<Option<Session>>>,     // SSH会话对象（线程安全）
    tcp_stream: Arc<Mutex<Option<TcpStream>>>, // TCP连接流（线程安全）
    channels: Arc<Mutex<HashMap<String, Channel>>>, // 活动通道映射表（线程安全）
    created_at: Instant,                      // 连接创建时间
    last_activity: Arc<Mutex<Instant>>,       // 最后活动时间（线程安全）
}

impl SshConnection {
    // 创建新的SSH连接实例
    // 参数: config - 连接配置信息
    // 返回: 新的SshConnection实例
    pub fn new(config: ConnectionConfig) -> Self {
        let now = Instant::now(); // 获取当前时间戳
        
        Self {
            id: config.id.clone(),                                    // 复制连接ID
            config,                                                   // 存储配置信息
            status: Arc::new(RwLock::new(ConnectionStatus::Disconnected)), // 初始状态为未连接
            session: Arc::new(Mutex::new(None)),                      // 初始化空的会话
            tcp_stream: Arc::new(Mutex::new(None)),                   // 初始化空的TCP流
            channels: Arc::new(Mutex::new(HashMap::new())),           // 初始化空的通道映射
            created_at: now,                                          // 设置创建时间
            last_activity: Arc::new(Mutex::new(now)),                 // 设置最后活动时间
        }
    }

    // 异步连接到SSH服务器
    // 返回: Result<(), String> - 成功返回()，失败返回错误信息
    pub async fn connect(&self) -> Result<(), String> {
        // 更新连接状态为正在连接
        {
            let mut status = self.status.write().await; // 获取状态写锁
            *status = ConnectionStatus::Connecting;      // 设置为连接中状态
        }

        // 建立TCP连接到SSH服务器，设置连接超时
        let tcp_stream = tokio::task::spawn_blocking({
            let host = self.config.ssh_config.host.clone();
            let port = self.config.ssh_config.port;
            let timeout_secs = self.config.ssh_config.connect_timeout.unwrap_or(30);
            move || {
                let addr = format!("{}:{}", host, port);
                println!("[DEBUG] 尝试连接到 {}, 超时时间: {}秒", addr, timeout_secs);
                
                match std::net::TcpStream::connect_timeout(
                    &addr.parse().map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidInput, e))?,
                    std::time::Duration::from_secs(timeout_secs)
                ) {
                    Ok(stream) => {
                        println!("[DEBUG] TCP连接成功建立");
                        // 设置TCP选项以提高性能
                        let _ = stream.set_nodelay(true);
                        let _ = stream.set_read_timeout(Some(std::time::Duration::from_secs(30)));
                        let _ = stream.set_write_timeout(Some(std::time::Duration::from_secs(30)));
                        Ok(stream)
                    }
                    Err(e) => {
                        println!("[ERROR] TCP连接失败: {}", e);
                        Err(e)
                    }
                }
            }
        }).await
            .map_err(|e| format!("任务执行失败: {}", e))?
            .map_err(|e| format!("TCP连接失败: {}", e))?;

        // 创建SSH会话
        let mut session = Session::new().map_err(|e| {
            format!("创建SSH会话失败: {}", e) // SSH会话创建失败的错误信息
        })?;

        // 设置SSH会话的TCP流
        session.set_tcp_stream(tcp_stream.try_clone().map_err(|e| {
            format!("复制TCP流失败: {}", e) // TCP流复制失败的错误信息
        })?);

        // 执行SSH握手
        session.handshake().map_err(|e| {
            format!("SSH握手失败: {}", e) // SSH握手失败的错误信息
        })?;

        // 根据配置的认证方法进行身份验证
        println!("开始SSH认证，用户名: {}", self.config.ssh_config.username);
        match &self.config.ssh_config.auth_method {
            AuthMethod::Password(password) => {
                println!("使用密码认证，密码长度: {}", password.len());
                // 使用密码认证
                session.userauth_password(&self.config.ssh_config.username, password)
                    .map_err(|e| {
                        println!("密码认证失败，错误: {}", e);
                        format!("密码认证失败: {}", e)
                    })?;
                println!("密码认证成功");
            }
            AuthMethod::PublicKey { private_key_path, passphrase } => {
                println!("使用公钥认证，私钥路径: {}, 是否有密码: {}", private_key_path, passphrase.is_some());
                // 使用公钥认证
                let private_key = Path::new(private_key_path); // 创建私钥路径对象
                let public_key = None; // 公钥路径（自动推导）
                
                // 检查私钥文件是否存在
                if !private_key.exists() {
                    let error_msg = format!("私钥文件不存在: {}", private_key_path);
                    println!("{}", error_msg);
                    return Err(error_msg);
                }
                
                // 执行公钥认证
                session.userauth_pubkey_file(
                    &self.config.ssh_config.username,     // 用户名
                    public_key,                     // 公钥路径（可选）
                    private_key,                    // 私钥路径
                    passphrase.as_deref(),          // 私钥密码（可选）
                ).map_err(|e| {
                    println!("公钥认证失败，错误: {}", e);
                    format!("公钥认证失败: {}", e)
                })?;
                println!("公钥认证成功");
            }
            AuthMethod::Agent => {
                println!("使用SSH Agent认证");
                // 使用SSH Agent认证
                session.userauth_agent(&self.config.ssh_config.username)
                    .map_err(|e| {
                        println!("SSH Agent认证失败，错误: {}", e);
                        format!("SSH Agent认证失败: {}", e)
                    })?;
                println!("SSH Agent认证成功");
            }
        }

        // 验证认证是否成功
        if !session.authenticated() {
            let error_msg = "SSH认证失败 - 认证状态检查失败".to_string();
            println!("{}", error_msg);
            let mut status = self.status.write().await;
            *status = ConnectionStatus::Error(error_msg.clone());
            return Err(error_msg);
        }
        println!("SSH认证验证成功，连接已建立");

        // 保存会话和TCP流到结构体中
        {
            let mut session_guard = self.session.lock().await; // 获取会话互斥锁
            *session_guard = Some(session);                     // 存储会话对象
        }
        
        {
            let mut stream_guard = self.tcp_stream.lock().await; // 获取TCP流互斥锁
            *stream_guard = Some(tcp_stream);                    // 存储TCP流对象
        }

        // 更新连接状态为已连接
        {
            let mut status = self.status.write().await; // 获取状态写锁
            *status = ConnectionStatus::Connected;       // 设置为已连接状态
        }

        // 更新最后活动时间
        {
            let mut last_activity = self.last_activity.lock().await; // 获取最后活动时间锁
            *last_activity = Instant::now();                          // 更新为当前时间
        }

        Ok(()) // 连接成功
    }

    // 断开SSH连接
    // 返回: Result<(), String> - 成功返回()，失败返回错误信息
    pub async fn disconnect(&self) -> Result<(), String> {
        // 关闭所有活动通道
        {
            let mut channels = self.channels.lock().await; // 获取通道映射锁
            for (_, mut channel) in channels.drain() {     // 遍历并清空所有通道
                let _ = channel.close();                    // 关闭通道（忽略错误）
            }
        }

        // 关闭SSH会话
        {
            let mut session_guard = self.session.lock().await; // 获取会话锁
            if let Some(session) = session_guard.take() {      // 取出会话对象
                let _ = session.disconnect(None, "用户断开连接", None); // 断开会话
            }
        }

        // 关闭TCP连接
        {
            let mut stream_guard = self.tcp_stream.lock().await; // 获取TCP流锁
            if let Some(stream) = stream_guard.take() {          // 取出TCP流对象
                let _ = stream.shutdown(std::net::Shutdown::Both); // 关闭TCP连接
            }
        }

        // 更新连接状态为已断开
        {
            let mut status = self.status.write().await;  // 获取状态写锁
            *status = ConnectionStatus::Disconnected;     // 设置为断开状态
        }

        Ok(()) // 断开成功
    }

    // 创建新的SSH通道用于执行命令或传输数据
    // 参数: channel_id - 通道唯一标识符
    // 返回: Result<(), String> - 成功返回()，失败返回错误信息
    pub async fn create_channel(&self, channel_id: String) -> Result<(), String> {
        // 检查连接状态
        {
            let status = self.status.read().await; // 获取状态读锁
            if *status != ConnectionStatus::Connected { // 检查是否已连接
                return Err("SSH连接未建立".to_string());
            }
        }

        // 获取SSH会话并创建通道
        let channel = {
            let session_guard = self.session.lock().await; // 获取会话锁
            match session_guard.as_ref() {                  // 检查会话是否存在
                Some(session) => {
                    // 创建新的SSH通道
                    session.channel_session().map_err(|e| {
                        format!("创建SSH通道失败: {}", e)
                    })?
                }
                None => {
                    return Err("SSH会话不存在".to_string());
                }
            }
        };

        // 将通道添加到通道映射表中
        {
            let mut channels = self.channels.lock().await; // 获取通道映射锁
            channels.insert(channel_id, channel);          // 插入新通道
        }

        // 更新最后活动时间
        {
            let mut last_activity = self.last_activity.lock().await; // 获取最后活动时间锁
            *last_activity = Instant::now();                          // 更新为当前时间
        }

        Ok(()) // 通道创建成功
    }

    // 在指定通道中执行命令
    // 参数: channel_id - 通道标识符, command - 要执行的命令
    // 返回: Result<String, String> - 成功返回命令输出，失败返回错误信息
    pub async fn execute_command(&self, channel_id: &str, command: &str) -> Result<String, String> {
        // 获取指定的通道
        let mut channel = {
            let mut channels = self.channels.lock().await; // 获取通道映射锁
            match channels.remove(channel_id) {            // 移除并获取通道
                Some(channel) => channel,
                None => {
                    return Err(format!("通道 {} 不存在", channel_id));
                }
            }
        };

        // 执行命令
        channel.exec(command).map_err(|e| {
            format!("执行命令失败: {}", e) // 命令执行失败的错误信息
        })?;

        // 读取命令输出
        let mut output = String::new(); // 创建输出字符串缓冲区
        channel.read_to_string(&mut output).map_err(|e| {
            format!("读取命令输出失败: {}", e) // 读取输出失败的错误信息
        })?;

        // 等待命令执行完成并关闭通道
        channel.wait_close().map_err(|e| {
            format!("等待命令完成失败: {}", e) // 等待完成失败的错误信息
        })?;

        // 获取命令退出状态
        let exit_status = channel.exit_status().map_err(|e| {
            format!("获取退出状态失败: {}", e) // 获取退出状态失败的错误信息
        })?;

        // 检查命令是否成功执行
        if exit_status != 0 {
            return Err(format!("命令执行失败，退出码: {}", exit_status));
        }

        // 更新最后活动时间
        {
            let mut last_activity = self.last_activity.lock().await; // 获取最后活动时间锁
            *last_activity = Instant::now();                          // 更新为当前时间
        }

        Ok(output) // 返回命令输出
    }

    // 获取当前连接状态
    // 返回: ConnectionStatus - 当前连接状态
    pub async fn get_status(&self) -> ConnectionStatus {
        let status = self.status.read().await; // 获取状态读锁
        status.clone()                          // 返回状态副本
    }

    // 检查连接是否处于活动状态
    // 返回: bool - true表示连接活跃，false表示连接不活跃
    pub async fn is_connected(&self) -> bool {
        let status = self.status.read().await;           // 获取状态读锁
        matches!(*status, ConnectionStatus::Connected)   // 检查是否为已连接状态
    }

    // 获取连接的最后活动时间
    // 返回: Instant - 最后活动时间戳
    pub async fn get_last_activity(&self) -> Instant {
        let last_activity = self.last_activity.lock().await; // 获取最后活动时间锁
        *last_activity                                        // 返回时间戳副本
    }

    // 发送保活数据包以维持连接
    // 返回: Result<(), String> - 成功返回()，失败返回错误信息
    pub async fn send_keepalive(&self) -> Result<(), String> {
        // 检查连接状态
        {
            let status = self.status.read().await; // 获取状态读锁
            if *status != ConnectionStatus::Connected { // 检查是否已连接
                return Err("连接未建立，无法发送保活包".to_string());
            }
        }

        // 发送保活数据包
        {
            let session_guard = self.session.lock().await; // 获取会话锁
            match session_guard.as_ref() {                  // 检查会话是否存在
                Some(session) => {
                    // 发送保活包
                    session.keepalive_send().map_err(|e| {
                          format!("发送保活包失败: {}", e)
                      })?;
                }
                None => {
                    return Err("SSH会话不存在".to_string());
                }
            }
        }

        // 更新最后活动时间
        {
            let mut last_activity = self.last_activity.lock().await; // 获取最后活动时间锁
            *last_activity = Instant::now();                          // 更新为当前时间
        }

        Ok(()) // 保活包发送成功
    }
}

// SSH连接管理器 - 管理多个SSH连接的生命周期
pub struct SshManager {
    connections: Arc<RwLock<HashMap<String, Arc<SshConnection>>>>, // 连接映射表（线程安全）
    max_connections: usize,                                       // 最大连接数限制
}

impl SshManager {
    // 创建新的SSH连接管理器
    // 参数: max_connections - 最大连接数限制
    // 返回: 新的SshManager实例
    pub fn new(max_connections: usize) -> Self {
        Self {
            connections: Arc::new(RwLock::new(HashMap::new())), // 初始化空的连接映射
            max_connections,                                     // 设置最大连接数
        }
    }

    // 添加新的SSH连接
    // 参数: config - 连接配置信息
    // 返回: Result<Arc<SshConnection>, String> - 成功返回连接对象，失败返回错误信息
    pub async fn add_connection(&self, config: ConnectionConfig) -> Result<Arc<SshConnection>, String> {
        // 检查连接数限制
        {
            let connections = self.connections.read().await; // 获取连接映射读锁
            if connections.len() >= self.max_connections {   // 检查是否超过最大连接数
                return Err(format!("连接数已达到最大限制: {}", self.max_connections));
            }
        }

        // 创建新的SSH连接
        let connection = Arc::new(SshConnection::new(config.clone())); // 创建连接对象
        let connection_id = config.id.clone();                        // 获取连接ID

        // 将连接添加到映射表中
        {
            let mut connections = self.connections.write().await; // 获取连接映射写锁
            connections.insert(connection_id, connection.clone()); // 插入新连接
        }

        Ok(connection) // 返回连接对象
    }

    // 获取指定ID的SSH连接
    // 参数: connection_id - 连接标识符
    // 返回: Option<Arc<SshConnection>> - 连接对象（如果存在）
    pub async fn get_connection(&self, connection_id: &str) -> Option<Arc<SshConnection>> {
        let connections = self.connections.read().await; // 获取连接映射读锁
        connections.get(connection_id).cloned()          // 获取并克隆连接对象
    }

    // 移除指定ID的SSH连接
    // 参数: connection_id - 连接标识符
    // 返回: Result<(), String> - 成功返回()，失败返回错误信息
    pub async fn remove_connection(&self, connection_id: &str) -> Result<(), String> {
        // 获取要移除的连接
        let connection = {
            let mut connections = self.connections.write().await; // 获取连接映射写锁
            connections.remove(connection_id)                     // 移除并获取连接
        };

        // 如果连接存在，先断开连接
        if let Some(connection) = connection {
            connection.disconnect().await?; // 断开SSH连接
        }

        Ok(()) // 移除成功
    }

    // 获取所有SSH连接的列表
    // 返回: Vec<Arc<SshConnection>> - 所有连接对象的向量
    pub async fn get_all_connections(&self) -> Vec<Arc<SshConnection>> {
        let connections = self.connections.read().await; // 获取连接映射读锁
        connections.values().cloned().collect()          // 收集所有连接对象
    }

    // 获取当前连接数量
    // 返回: usize - 当前连接数
    pub async fn get_connection_count(&self) -> usize {
        let connections = self.connections.read().await; // 获取连接映射读锁
        connections.len()                                // 返回连接数量
    }

    // 清理所有非活跃连接
    // 参数: inactive_timeout - 非活跃超时时间
    // 返回: Result<usize, String> - 成功返回清理的连接数，失败返回错误信息
    pub async fn cleanup_inactive_connections(&self, inactive_timeout: Duration) -> Result<usize, String> {
        let now = Instant::now();           // 获取当前时间
        let mut to_remove = Vec::new();     // 要移除的连接ID列表
        let mut cleanup_count = 0;          // 清理计数器

        // 查找需要清理的连接
        {
            let connections = self.connections.read().await; // 获取连接映射读锁
            for (id, connection) in connections.iter() {     // 遍历所有连接
                let last_activity = connection.get_last_activity().await; // 获取最后活动时间
                let status = connection.get_status().await;               // 获取连接状态
                
                // 检查连接是否需要清理
                let should_cleanup = match status {
                    ConnectionStatus::Error(_) => true,                           // 错误状态的连接
                    ConnectionStatus::Disconnected => true,                       // 已断开的连接
                    ConnectionStatus::Connected => {
                        now.duration_since(last_activity) > inactive_timeout     // 超时的连接
                    }
                    ConnectionStatus::Connecting => {
                        now.duration_since(last_activity) > Duration::from_secs(60) // 连接超时
                    }
                };

                if should_cleanup {
                    to_remove.push(id.clone()); // 添加到移除列表
                }
            }
        }

        // 移除需要清理的连接
        for connection_id in to_remove {
            if let Err(e) = self.remove_connection(&connection_id).await {
                eprintln!("清理连接 {} 时出错: {}", connection_id, e); // 打印清理错误
            } else {
                cleanup_count += 1; // 增加清理计数
            }
        }

        Ok(cleanup_count) // 返回清理的连接数
    }

    // 关闭所有SSH连接
    // 返回: Result<(), String> - 成功返回()，失败返回错误信息
    pub async fn shutdown_all(&self) -> Result<(), String> {
        let connection_ids: Vec<String> = {
            let connections = self.connections.read().await; // 获取连接映射读锁
            connections.keys().cloned().collect()            // 收集所有连接ID
        };

        // 逐个关闭所有连接
        for connection_id in connection_ids {
            if let Err(e) = self.remove_connection(&connection_id).await {
                eprintln!("关闭连接 {} 时出错: {}", connection_id, e); // 打印关闭错误
            }
        }

        Ok(()) // 关闭成功
    }
}

// 实现Default trait为SshManager提供默认构造函数
impl Default for SshManager {
    // 创建默认的SSH连接管理器（最大连接数为10）
    fn default() -> Self {
        Self::new(10) // 默认最大连接数为10
    }
}

// SSH连接工具函数模块
pub mod utils {
    use super::*;

    // 测试SSH连接的可达性
    // 参数: host - 主机地址, port - 端口号, timeout_secs - 超时秒数
    // 返回: Result<bool, String> - 成功返回连接状态，失败返回错误信息
    pub async fn test_connection(host: &str, port: u16, timeout_secs: u64) -> Result<bool, String> {
        // 尝试建立TCP连接测试可达性
        let result = timeout(
            Duration::from_secs(timeout_secs), // 设置超时时间
            tokio::task::spawn_blocking({
                let host = host.to_string();
                move || {
                    std::net::TcpStream::connect(format!("{}:{}", host, port))
                }
            })
        ).await;

        match result {
            Ok(Ok(Ok(_))) => Ok(true),                                // 连接成功
            Ok(Ok(Err(e))) => Err(format!("连接失败: {}", e)),        // 连接失败
            Ok(Err(e)) => Err(format!("任务执行失败: {}", e)),        // 任务失败
            Err(_) => Err("连接超时".to_string()),                    // 连接超时
        }
    }

    // 验证SSH私钥文件的有效性
    // 参数: private_key_path - 私钥文件路径
    // 返回: Result<bool, String> - 成功返回验证结果，失败返回错误信息
    pub fn validate_private_key(private_key_path: &str) -> Result<bool, String> {
        use std::fs; // 文件系统操作
        
        // 检查文件是否存在
        if !Path::new(private_key_path).exists() {
            return Err("私钥文件不存在".to_string());
        }

        // 读取私钥文件内容
        let key_content = fs::read_to_string(private_key_path)
            .map_err(|e| format!("读取私钥文件失败: {}", e))?;

        // 简单验证私钥格式（检查是否包含私钥标识）
        let is_valid = key_content.contains("-----BEGIN") && 
                      key_content.contains("PRIVATE KEY-----") &&
                      key_content.contains("-----END");

        if is_valid {
            Ok(true) // 私钥格式有效
        } else {
            Err("私钥文件格式无效".to_string()) // 私钥格式无效
        }
    }

    // 生成SSH连接的唯一标识符
    // 参数: host - 主机地址, port - 端口号, username - 用户名
    // 返回: String - 唯一标识符
    pub fn generate_connection_id(host: &str, port: u16, username: &str) -> String {
        use std::collections::hash_map::DefaultHasher; // 默认哈希器
        use std::hash::{Hash, Hasher};                 // 哈希trait
        
        let mut hasher = DefaultHasher::new();                    // 创建哈希器
        format!("{}:{}@{}", username, port, host).hash(&mut hasher); // 计算哈希值
        format!("ssh_{:x}", hasher.finish())                      // 返回十六进制哈希字符串
    }
}

// 单元测试模块
#[cfg(test)]
mod tests {
    use super::*;
    use crate::config::{ConnectionConfig, SshConfig};

    // 测试SSH连接的创建
    #[tokio::test]
    async fn test_ssh_connection_creation() {
        // 创建测试用的连接配置
        let config = ConnectionConfig {
            id: "test_connection".to_string(),           // 连接ID
            name: "Test Connection".to_string(),         // 连接名称
            ssh: SshConfig {
                host: "localhost".to_string(),            // 主机地址
                port: 22,                                 // SSH端口
                username: "testuser".to_string(),         // 用户名
                auth_method: AuthMethod::Password("password".to_string()), // 认证方法
                connect_timeout: Some(30),                // 连接超时
                keepalive_interval: Some(60),             // 保活间隔
                compression: false,                       // 不启用压缩
            },
            tunnel: None,                                 // 无隧道配置
            terminal: None,                               // 无终端配置覆盖
            tags: vec![],                                 // 无标签
            notes: None,                                  // 无备注
            created_at: chrono::Utc::now(),               // 创建时间
            last_used: None,                              // 最后使用时间
        };

        // 创建SSH连接实例
        let connection = SshConnection::new(config);
        
        // 验证连接初始状态
        assert_eq!(connection.id, "test_connection");                    // 检查连接ID
        assert_eq!(connection.get_status().await, ConnectionStatus::Disconnected); // 检查初始状态
        assert!(!connection.is_connected().await);                       // 检查连接状态
    }

    // 测试SSH管理器的功能
    #[tokio::test]
    async fn test_ssh_manager() {
        let manager = SshManager::new(5); // 创建最大连接数为5的管理器
        
        // 验证初始状态
        assert_eq!(manager.get_connection_count().await, 0); // 检查初始连接数
        
        // 创建测试配置
        let config = ConnectionConfig {
            id: "test_manager_connection".to_string(),   // 连接ID
            name: "Test Manager Connection".to_string(), // 连接名称
            ssh: SshConfig {
                host: "localhost".to_string(),            // 主机地址
                port: 22,                                 // SSH端口
                username: "testuser".to_string(),         // 用户名
                auth_method: AuthMethod::Password("password".to_string()), // 认证方法
                connect_timeout: Some(30),                // 连接超时
                keepalive_interval: Some(60),             // 保活间隔
                compression: false,                       // 不启用压缩
            },
            tunnel: None,                                 // 无隧道配置
            terminal: None,                               // 无终端配置覆盖
            tags: vec![],                                 // 无标签
            notes: None,                                  // 无备注
            created_at: chrono::Utc::now(),               // 创建时间
            last_used: None,                              // 最后使用时间
        };
        
        // 添加连接到管理器
        let connection = manager.add_connection(config).await.unwrap();
        
        // 验证连接已添加
        assert_eq!(manager.get_connection_count().await, 1);              // 检查连接数
        assert!(manager.get_connection("test_manager_connection").await.is_some()); // 检查连接存在
        
        // 移除连接
        manager.remove_connection("test_manager_connection").await.unwrap();
        
        // 验证连接已移除
        assert_eq!(manager.get_connection_count().await, 0);              // 检查连接数
        assert!(manager.get_connection("test_manager_connection").await.is_none()); // 检查连接不存在
    }

    // 测试连接工具函数
    #[tokio::test]
    async fn test_connection_utils() {
        // 测试连接ID生成
        let id1 = utils::generate_connection_id("localhost", 22, "user1"); // 生成连接ID
        let id2 = utils::generate_connection_id("localhost", 22, "user2"); // 生成另一个连接ID
        
        assert_ne!(id1, id2);                    // 验证不同用户生成不同ID
        assert!(id1.starts_with("ssh_"));        // 验证ID格式
        assert!(id2.starts_with("ssh_"));        // 验证ID格式
        
        // 测试相同参数生成相同ID
        let id3 = utils::generate_connection_id("localhost", 22, "user1"); // 再次生成相同参数的ID
        assert_eq!(id1, id3);                    // 验证相同参数生成相同ID
    }
}